package ofpof.database;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.FactoryBean;

import com.mongodb.DBAddress;
import com.mongodb.Mongo;
import com.mongodb.MongoOptions;

public class MongoDatasourceFactory implements FactoryBean<Mongo> {

	private static final String DEFAULT_DB_ADDRESS = "localhost:27017";
	private String masterAddress = DEFAULT_DB_ADDRESS;
	private String slaveAddress;

	private int connectionsPerHost;
	private boolean autoConnectRetry;
	private int connectionTimeout;
	private int maxWaitTime;
	private int socketTimeout;
	private int threadsAllowedToBlockForConnectionMultiplier; 

	@Override
	public Mongo getObject() throws Exception {
		Mongo mongo = null;
		MongoOptions mongoOptions = prepareMongoOptions();
		
		if (StringUtils.isNotEmpty(slaveAddress)) {
			mongo = new Mongo(new DBAddress(masterAddress),new DBAddress(slaveAddress),mongoOptions);
		} else {
			 mongo = new Mongo(masterAddress,mongoOptions);
		}
		return mongo;
	}

	@Override
	public Class<?> getObjectType() {
		return Mongo.class;
	}

	@Override
	public boolean isSingleton() {
		return true;
	}

	public void setMasterAddress(String masterAddress) {
		this.masterAddress = masterAddress;
	}

	public void setSlaveAddress(String slaveAddress) {
		this.slaveAddress = slaveAddress;
	}

	public int getSocketTimeout() {
		return socketTimeout;
	}

	public void setSocketTimeout(int socketTimeout) {
		this.socketTimeout = socketTimeout;
	}

	public void setConnectionsPerHost(int connectionsPerHost) {
		this.connectionsPerHost = connectionsPerHost;
	}

	public void setAutoConnectRetry(boolean autoConnectRetry) {
		this.autoConnectRetry = autoConnectRetry;
	}

	public void setConnectionTimeout(int connectionTimeout) {
		this.connectionTimeout = connectionTimeout;
	}

	public void setMaxWaitTime(int maxWaitTime) {
		this.maxWaitTime = maxWaitTime;
	}

	public void setThreadsAllowedToBlockForConnectionMultiplier(
			int threadsAllowedToBlockForConnectionMultiplier) {
		this.threadsAllowedToBlockForConnectionMultiplier = threadsAllowedToBlockForConnectionMultiplier;
	}
	
	private MongoOptions prepareMongoOptions() {
		MongoOptions mongoOptions = new MongoOptions();
		mongoOptions.autoConnectRetry = autoConnectRetry;
		mongoOptions.connectionsPerHost = connectionsPerHost;
		mongoOptions.connectTimeout = connectionTimeout;
		mongoOptions.socketTimeout = socketTimeout;
		mongoOptions.threadsAllowedToBlockForConnectionMultiplier = threadsAllowedToBlockForConnectionMultiplier;
		mongoOptions.maxWaitTime = maxWaitTime;
		return mongoOptions;
		
	}
}
